<?php
namespace app\mpbase\controller;

use app\mpbase\service\Config as ConfigService;
use app\mpbase\service\Wechat as WechatService;
use app\common\model\Order as OrderModel;
use app\common\model\User as UserModel;
use app\common\model\WechatAutoreply;
use app\common\model\WechatConfig;
use app\common\model\WechatContext;
use app\common\model\WechatResponse;
use EasyWeChat\Foundation\Application;
use EasyWeChat\Payment\Order;
use think\Controller;
use think\Log;
use think\Request;

/**
 * 微信小程序 相关接口
 */
class WechatApp extends Controller
{
    public $app = null;
    public $miniProgram = null;
    public $appletId = null;
    public $options = [];

    protected function _initialize()
    {
        parent::_initialize();
        //公众号初始化
        $appletId = Request::instance()->header('appletId');
        $this->appletId = $appletId = empty($appletId)? input('appletId'):$appletId;
        //获取公众号配置信息
        $this->options = ConfigService::load($appletId);
        $this->app = new Application($this->options);
        $this->miniProgram = $this->app->mini_program;
    }

    //获取用户SessionKey
    public function code()
    {
        $code = input('code');
        $response = $this->miniProgram->sns->getSessionKey($code);
        return json_decode($response,true);
    }

    //获取用户信息
    public function decryptData()
    {
        //获取用户SessionKey
        $code = input('code');
        $iv = input('iv');
        $encryptedData = input('encryptedData');
        $session = $this->miniProgram->sns->getSessionKey($code);
        $session != null && $session = json_decode($session,true);
        //用户信息 解码
        if(isset($session['session_key'])){
            $response =  $this->miniProgram->encryptor->decryptData($session['session_key'],$iv,$encryptedData);
            $data = [
                'openid'=>$response['openId'],
                'union_id'=>$response['unionId'],
                'nickname'=>$response['nickName'],
                'gender'=>$response['gender'],
                'language'=>$response['language'],
                'city'=>$response['city'],
                'province'=>$response['province'],
                'country'=>$response['country'],
                'avatar'=>$response['avatarUrl'],
            ];
            $res = (new UserModel())->saveInfo($data);
            return $res;
        }else{
            return $session;
        }
    }

    //消息推送
    public function api()
    {
        $this->appletid = input('appletid');
        $this->app = new Application(ConfigService::load($this->appletid));
        $this->app->server->setMessageHandler(function ($message) {

            $WechatService = new WechatService;
            $WechatContext = new WechatContext;
            $WechatResponse = new WechatResponse;

            $openid = $message->FromUserName;
            $to_openid = $message->ToUserName;
            $event = $message->Event;
            $eventkey = $message->EventKey ? $message->EventKey : $message->Event;

            $unknownmessage = WechatConfig::value('default.unknown.message');
            $unknownmessage = $unknownmessage ? $unknownmessage : "未找到对应指令!";

            switch ($message->MsgType) {
                case 'event': //事件消息
                    switch ($event) {
                        case 'subscribe'://添加关注
                            $subscribemessage = WechatConfig::value('default.subscribe.message');
                            $subscribemessage = $subscribemessage ? $subscribemessage : "欢迎关注我们!";
                            return $subscribemessage;
                        case 'unsubscribe'://取消关注
                            return '';
                        case 'LOCATION'://获取地理位置
                            return '';
                        case 'VIEW': //跳转链接,eventkey为链接
                            return '';
                        default:
                            break;
                    }

                    $response = $WechatResponse->where(["eventkey" => $eventkey, "appletid" => $this->appletid, 'status' => 'normal'])->find();
                    if ($response) {
                        $content = (array)json_decode($response['content'], TRUE);
                        $context = $WechatContext->where(['openid' => $openid])->find();
                        $data = ['eventkey' => $eventkey, 'command' => '', 'refreshtime' => time(), 'openid' => $openid];
                        if ($context) {
                            $WechatContext->data($data)->where('id', $context['id'])->update();
                            $data['id'] = $context['id'];
                        } else {
                            $id = $WechatContext->data($data)->save();
                            $data['id'] = $id;
                        }
                        $result = $WechatService->response($this, $openid, $content, $data);
                        if ($result) {
                            return $result;
                        }
                    }
                    return $unknownmessage;
                case 'text': //文字消息
                case 'image': //图片消息
                case 'voice': //语音消息
                case 'video': //视频消息
                case 'location': //坐标消息
                case 'link': //链接消息
                default: //其它消息
                    //上下文事件处理
                    $context = $WechatContext->where(['openid' => ['=', $openid], 'refreshtime' => ['>=', time() - 1800]])->find();
                    if ($context && $context['eventkey']) {
                        $response = $WechatResponse->where(['eventkey' => $context['eventkey'], "appletid" => $this->appletid, 'status' => 'normal'])->find();
                        if ($response) {
                            $WechatContext->data(array('refreshtime' => time()))->where('id', $context['id'])->update();
                            $content = (array)json_decode($response['content'], TRUE);
                            $result = $WechatService->command($this, $openid, $content, $context);
                            if ($result) {
                                return $result;
                            }
                        }
                    }
                    //自动回复处理
                    if ($message->MsgType == 'text') {
                        $wechat_autoreply = new WechatAutoreply();
                        $autoreply = $wechat_autoreply->where(['text' => $message->Content, "appletid" => $this->appletid, 'status' => 'normal'])->find();
                        if ($autoreply) {
                            $response = $WechatResponse->where(["eventkey" => $autoreply['eventkey'], "appletid" => $this->appletid, 'status' => 'normal'])->find();
                            if ($response) {
                                $content = (array)json_decode($response['content'], TRUE);
                                $context = $WechatContext->where(['openid' => $openid])->find();
                                $result = $WechatService->response($this, $openid, $content, $context);
                                if ($result) {
                                    return $result;
                                }
                            }
                        }
                    }
                    return $unknownmessage;
            }
            return ""; //SUCCESS
        });
        $response = $this->app->server->serve();
        // 将响应输出
        $response->send();
    }

    //订单支付
    public function pay()
    {
        $orderNo = input('order_no');
        $order = OrderModel::get(['order_no'=>$orderNo]);
        if(!$order)
            $this->error('订单不存在');
        $mpConfig = get_applet_info();
        $attributes = [
            'trade_type'       => 'JSAPI', // JSAPI，NATIVE，APP...
            'body'             => $order->order_name,
            'detail'           => $order->order_name,
            'out_trade_no'     => $order->order_no,
//          'total_fee'        => $order->payment_price * 100, // 单位：分
            'total_fee'        => 1, // 单位：分
            'openid'           => $order->openid,
//          'notify_url'       => $mpConfig['notify_url'].'/appletId/'.$this->appletId,
            //XDebug 断点参数
            'notify_url'       => $mpConfig['notify_url'].'/appletId/'.$this->appletId.'/XDEBUG_SESSION_START/PHPSTORM',

            // 如果传入sub_openid, 请在实例化Application时, 同时传入$sub_app_id, $sub_merchant_id
//            'sub_openid'        => '当前用户的 openid',
        ];

        $order = new Order($attributes);
        $payment = $this->app->payment;
        $result = $payment->prepare($order);

        if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
            $prepayId = $result->prepay_id;
            $json = $payment->configForJSSDKPayment($prepayId);
            return $json;
        }else{
            return $result;
        }

    }

    /**
     * 支付回调
     */
    public function payNotify()
    {
        Log::record(file_get_contents('php://input'), "notify");
        $response = $this->app->payment->handleNotify(function ($notify, $successful) {
            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $order = OrderModel::get(['trans_id'=>$notify->transaction_id]);
            if ($order) {
                //订单已处理
                return true;
            }
            $order = OrderModel::get(['order_no'=>$notify->out_trade_no]);
            if (!$order) {
                // 如果订单不存在告诉微信，我已经处理完了，订单没找到，别再通知我了
                return 'Order not exist.';
            }
            // 如果订单存在
            // 用户是否支付成功
            if ($successful) {
                // 请在这里编写处理成功的处理逻辑
                $order->trans_id = $notify->transaction_id;
                $order->payment_time = time();
                $order->status = OrderModel::ORDER_WAIT_SEND;
                $order->save();
            }
            return true;
        });
        $response->send();
    }
}